iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0

Medium 清新閱讀版連結

前一天我們把環境建立好了,今天我們來寫第一個單元測試吧!
不過在那之前,先讓我們了解單元測試的「3個A」

單元測試3A

所謂的「3個A」,是指以下三個英文單字:

  • Arrange:初始化工作,如準備假資料
  • Act:執行測試對象
  • Assert:驗證結果

一個良好的單元測試案例,應該包含以上的結構,
依序執行 Arrange → Act → Assert,
並顯示驗證結果,這樣就是一個完整的單元測試程式。

第一個測試

事不宜遲,馬上來寫測試吧!

在開始撰寫第一個測試前,先讓我們做一個待測對象,
我們以一個計算BMI的函數為例子吧!

app\Services 資料夾下,建立 TestService.php

<?php

namespace App\Services;

class TestService
{
    public function calculateBmi(float $height, float $weight): float
    {
        if ($weight <= 0) {
            return 0.0;
        }

        return $weight / ($height * $height);
    }
}

接著馬上來建立測試,在 workspace 容器內,專案資料夾下執行以下指令,建立單元測試:

php artisan make:test TestServiceTest --unit

建立 TestServiceTest.php 後,讓我們來撰寫測試函數吧:

<?php

namespace Tests\Unit;

use App\Services\TestService;
use PHPUnit\Framework\TestCase;

class TestServiceTest extends TestCase
{
    /**
     * Test calculateBmi
     */
    public function testCalculateBmi()
    {
        // Arrange
        // 初始化待測對象
        // 以及執行測試所需的資料
        $service = app(TestService::class);
        $height = 1.6;
        $weight = 64.0;

        // Act
        // 執行欲測試的函數/程式碼區塊/行為
        $actualBmi = $service->calculateBmi($height, $weight);

        // Assert
        // 驗證測試結果
        $expectedBmi = 25;
        $this->assertEquals($actualBmi, $expectedBmi);
    }
}

首先,先來解釋各個區塊程式碼邏輯:

// Arrange
// 初始化待測對象
// 以及執行測試所需的資料
$service = app(TestService::class);
$height = 1.6;
$weight = 64.0;

這邊先建立1個 TestService 的實例 $service
並初始化稍候執行待測對象時,所需的資料。

// Act
// 執行欲測試的函數/程式碼區塊/行為
$actualBmi = $service->calculateBmi($height, $weight);

這邊就是執行要測試的程式碼區塊。

// Assert
  // 驗證測試結果
  $expectedBmi = 25;
  $this->assertEquals($actualBmi, $expectedBmi);

進行驗證,其中 $this→assertEquals 是目前我們所用到的第一個 Assert 函數,
它用來驗證第一個輸入值(實際值)是否與第二個(期望值)輸入值相等。

待測對象與測試案例都準備好後,就讓我們來執行測試吧:

./vendor/bin/phpunit

應該會看到以下輸出結果:

恭喜完成第一個單元測試!
是不是很簡單呢?

明天來介紹常用的 Assert 函數。

參考資料


上一篇
環境建置
下一篇
常用 Assertion 函數(一)
系列文
自動化測試大作戰31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言